package com.egao.common.module.company.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.egao.common.core.exception.BusinessException;
import com.egao.common.core.exception.ParameterException;
import com.egao.common.core.web.JsonResult;
import com.egao.common.core.web.PageParam;
import com.egao.common.module.company.constants.FieldConstants;
import com.egao.common.module.company.entity.Field;
import com.egao.common.module.company.entity.FieldRecord;
import com.egao.common.module.company.entity.Preach;
import com.egao.common.module.company.entity.vo.FieldFormVO;
import com.egao.common.module.company.entity.vo.FieldListVO;
import com.egao.common.module.company.entity.vo.FieldRecordFormVO;
import com.egao.common.module.company.mapper.FieldMapper;
import com.egao.common.module.company.service.FieldRecordService;
import com.egao.common.module.company.service.FieldService;
import com.egao.common.module.company.service.PreachService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 场地信息(Field)表服务实现类
 *
 * @author dl
 */
@Service
@Slf4j
public class FieldServiceImpl extends ServiceImpl<FieldMapper, Field> implements FieldService {

    @Autowired
    private FieldRecordService fieldRecordService;

    @Autowired
    private PreachService preachService;

    @Override
    public JsonResult list(PageParam<FieldListVO> pageParam) {

        // 查询所有的场地
        List<Field> fieldList = baseMapper.selectList(new QueryWrapper<Field>().orderByAsc("sort"));

        Map<String, Object> map = pageParam.getPageData();
        // 如果未选择查询日期，默认为今天
        Date date = null;
        if (map.get(FieldConstants.QUERY_DATE) != null) {
            String queryDate = (String) map.get(FieldConstants.QUERY_DATE);
            date = DateUtil.parse(queryDate);
        } else {
            date = DateUtil.date();
        }
        // 获取本周的开始日期
        Date monDay = DateUtil.beginOfWeek(date, true);

        // 获取预约记录
        List<FieldRecordFormVO> fieldRecordFormVOList = getWeekFieldRecordList(monDay);

        //周日期及星期几
        List<Map<String, Object>> weekList = getWeekList(monDay);
        List<Map<String, Object>> list = new ArrayList<>();
        for (Field field : fieldList) {
            List<Map<String, Object>> weekTempList = new ArrayList<>();
            Map<String, Object> fieldMap = new HashMap<>(16);

            for (Map<String, Object> weekMap : weekList) {
                List<Map<String, Object>> slotList = new ArrayList<>();
                Map<String, Object> tempMap = new HashMap<>(16);
                for (int i = 1; i < FieldConstants.TIME_SLOT; i++) {
                    Map<String, Object> slotMap = new HashMap<>(16);
                    List<FieldRecordFormVO> records = this.compareStartDate(fieldRecordFormVOList, field.getId(), (String) weekMap.get("week") ,String.valueOf(i));
                    if (records.size() > 0) {
                        List<Map<String, Object>> list1 = new ArrayList<>();
                        records.forEach(d -> {
                            Map<String, Object> map1 = new HashMap<>(3);
                            Preach preach = preachService.getById(d.getBusinessId());
                            map1.put("const", preach != null ? preach.getTitle() : "场地已锁定");
                            map1.put("preachId", preach != null ? preach.getId() : "");
                            map1.put("color", true);
                            list1.add(map1);
                        });
                        slotMap.put("list", list1);
                        slotMap.put("state", true);
                        if (list1.size() == 1 && "场地已锁定".equals(list1.get(0).get("const"))) {
                            slotMap.put("lock", true);
                            slotMap.put("id", records.get(0).getId());
                        } else {
                            slotMap.put("lock", false);
                            slotMap.put("id", null);
                        }
                    } else {
                        slotMap.put("list", new ArrayList<>());
                        slotMap.put("const", "");
                        slotMap.put("state", false);
                    }
                    slotMap.put("name", String.valueOf(i));
                    slotMap.put("fieldId", field.getId());
                    slotList.add(slotMap);
                }
                tempMap.put("data", slotList);
                tempMap.put("week", weekMap.get("week"));
                weekTempList.add(tempMap);
            }
            fieldMap.put("id", field.getId());
            fieldMap.put("name", field.getName());
            fieldMap.put("type", field.getType());
            fieldMap.put("data", weekTempList);
            list.add(fieldMap);
        }
        Map<String, Object> result = new HashMap<>(16);
        result.put("weekList", weekList);
        result.put("dataList", list);
        return JsonResult.ok("查询成功").setData(result);
    }

    @Override
    public JsonResult queryList(PageParam<FieldListVO> pageParam) {

        // 查询参数
        Map<String, Object> map = pageParam.getPageData();

        // 查询所有的场地
        QueryWrapper<Field> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("sort");

        if (map.get("type") != null) {
            queryWrapper.eq("type", map.get("type"));
        }

        // 执行查询
        List<Field> fieldList = baseMapper.selectList(queryWrapper);

        // List<Field> fieldList = baseMapper.selectList(new QueryWrapper<Field>().orderByAsc("sort"));


        // 如果未选择查询日期，默认为查询当天的预约记录
        Date date = null;
        if (map.get(FieldConstants.QUERY_DATE) != null) {
            String queryDate = (String) map.get(FieldConstants.QUERY_DATE);
            date = DateUtil.parse(queryDate);
        } else {
            date = DateUtil.date();
        }
        // 查询所有场地当天的预约记录
        List<FieldRecordFormVO> fieldRecords = getDayFieldRecordList(date);
        Map<String, Object> result = new HashMap<>(16);
        result.put("fields", fieldList);
        result.put("fieldRecords", fieldRecords);
        return JsonResult.ok("查询成功").setData(result);
    }

    @Override
    public JsonResult saveField(FieldFormVO fieldFormVO) {
        if (fieldFormVO == null) {
            throw new ParameterException("场地为空");
        }

        Field field = new Field();
        BeanUtil.copyProperties(fieldFormVO, field);

        if (save(field)) {
            return JsonResult.ok("提交成功");
        }
        return JsonResult.error("提交失败");
    }

    @Override
    public JsonResult updateField(FieldFormVO fieldFormVO) {
        Field field = verifyFormData(fieldFormVO);
        BeanUtil.copyProperties(fieldFormVO, field);

        if (updateById(field)) {
            return JsonResult.ok("修改成功");
        }
        return JsonResult.error("修改失败");
    }

    @Override
    public JsonResult deleteField(FieldFormVO fieldFormVO) {
        Field field = verifyFormData(fieldFormVO);
        Integer count = getFieldRecordCount(fieldFormVO.getId());
        if (count > 0) {
            throw new ParameterException("场地有预约记录");
        }
        if (removeById(field)) {
            return JsonResult.ok("删除成功");
        }
        return JsonResult.error("删除失败");
    }

    @Override
    public JsonResult detail(Integer id) {
        if (id == null) {
            throw new ParameterException("场地为空");
        }

        Field field = getById(id);
        if (field == null) {
            throw new BusinessException("场地不存在");
        }

        FieldFormVO fieldFormVO = new FieldFormVO();
        BeanUtil.copyProperties(field, fieldFormVO);

        return JsonResult.ok("查询成功").setData(fieldFormVO);
    }

    @Override
    public JsonResult queryField(String holdTime, String type) {
        List<Field> fieldList = baseMapper.selectList(new QueryWrapper<Field>().orderByAsc("sort"));

        // 获取预约记录
        List<FieldRecordFormVO> fieldRecordFormVOList = getFieldRecordListByTime(holdTime);
        List<Map<String, Object>> list = new ArrayList<>();
        for (Field field : fieldList) {
            Map<String, Object> map = new HashMap<>();
            map.put("filedName", field.getName());
            map.put("id", field.getId());
            boolean state = false;
            String text = "可预约";

            List<String> stringList = new ArrayList<>();
            for (FieldRecordFormVO r : fieldRecordFormVOList) {
                if (r.getTimeType().equals(type) && r.getFieldId().equals(field.getId())) {
                    state = true;
                    if (r.getBusinessId() != null) {
                        Preach preach = preachService.getById(r.getBusinessId());
                        String time = DateUtil.format(preach.getHoldTime(), DatePattern.NORM_DATETIME_MINUTE_PATTERN);
                        String title = preach != null ? preach.getTitle() : "";
                        text = StrUtil.format("{} {}", time, title);
                    } else {
                        text = "已预订";
                    }
                    stringList.add(text);
                }
            }

            map.put("state", state);
            map.put("styleState", false);
            map.put("type", type);
            map.put("text", text);
            map.put("list", stringList);
            list.add(map);
        }
        return JsonResult.ok("查询成功").setData(list);
    }

    /**
     * 获取预约记录
     * @param date 预约时间
     * @return
     */
    private List<FieldRecordFormVO> getFieldRecordListByTime(String date) {
        PageParam<FieldRecordFormVO> page = new PageParam<>();
        page.put("createTimeStart", date + " 00:00:00");
        page.put("createTimeEnd", date + " 23:59:59");
        return fieldRecordService.listRecord(page);
    }

    /**
     * 查询是否有预约记录
     * @param fieldId 场地编号
     * @return Integer 预约数量
     */
    private Integer getFieldRecordCount(Integer fieldId) {
        QueryWrapper<FieldRecord> qw = new QueryWrapper<>();
        qw.eq("field_id", fieldId);
        return fieldRecordService.count(qw);
    }

    /**
     * 检验修改数据
     * @param fieldFormVO 场地表单
     * @return Field 场地
     */
    private Field verifyFormData(FieldFormVO fieldFormVO) {
        if (fieldFormVO == null) {
            throw new ParameterException("场地为空");
        }

        if (fieldFormVO.getId() == null) {
            throw new ParameterException("场地编号为空");
        }
        Field field = getById(fieldFormVO.getId());
        if (field == null) {
            throw new BusinessException("场地为空");
        }
        return field;
    }

    /** 
     * 获取每周的日期及星期
     * @param monDay 周一日期
     * @return 
     */
    private List<Map<String, Object>> getWeekList(Date monDay) {
        List<Map<String, Object>> weekList = new ArrayList<>();
        Map<String, Object> map1 = new HashMap<>(16);
        map1.put("week", DateUtil.format(monDay, "yyyy-MM-dd"));
        map1.put("name", FieldConstants.getWeekName(0));
        weekList.add(map1);


        for (int i = 1; i < FieldConstants.totalDay; i++) {
            Map<String, Object> hashMap = new HashMap<>(16);
            Date d = DateUtil.offsetDay(monDay, i);
            hashMap.put("week", DateUtil.format(d, "yyyy-MM-dd"));
            hashMap.put("name", FieldConstants.getWeekName(i));
            weekList.add(hashMap);
        }
        return weekList;
    }

    /**
     * 获取周预约记录
     * @param monday 周一日期
     * @return
     */
    private List<FieldRecordFormVO> getWeekFieldRecordList(Date monday) {
        Date sunday = DateUtil.offsetDay(monday, 6);
        PageParam<FieldRecordFormVO> page = new PageParam<>();
        page.put("createTimeStart", DateUtil.format(monday, "yyyy-MM-dd") + " 00:00:00");
        page.put("createTimeEnd", DateUtil.format(sunday, "yyyy-MM-dd") + " 23:59:59");
        page.setSize(200);
        return fieldRecordService.listRecord(page);
    }

    /**
     * 获取当天所有的预约记录
     * day = start_date & start_time > currentTimeStart & end_time < currentTimeEnd
     * @param day
     * @return
     */
    private List<FieldRecordFormVO> getDayFieldRecordList(Date day) {
        PageParam<FieldRecordFormVO> page = new PageParam<>();
        page.put("day", day);
        page.put("currentTimeStart", DateUtil.format( day, "yyyy-MM-dd") +  " 00:00:00");
        page.put("currentTimeEnd", DateUtil.format( day, "yyyy-MM-dd") +  " 23:59:59");
        page.setSize(200);
        return fieldRecordService.queryDayListRecord(page);
    }

    /**
     * 比较当前时间是否有预约记录
     * @param list 集合
     * @param fieldId 场地编号
     * @param startDate 预约时间
     * @param timeType 预约时段
     * @return
     */
    private List<FieldRecordFormVO> compareStartDate(List<FieldRecordFormVO> list, Integer fieldId, String startDate, String timeType) {
        List<FieldRecordFormVO> list1 = new ArrayList<>();
        for (FieldRecordFormVO f : list) {
            String d = DateUtil.format(f.getStartDate(), "yyyy-MM-dd");
            if (f.getFieldId().equals(fieldId) && startDate.equals(d) && timeType.equals(f.getTimeType())) {
                System.out.println(f.getFieldId() + "~" + fieldId);
                list1.add(f);
            }
        }
        return list1;
    }

}
